package com.ruoyi.system.service;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.InviteBids;
import com.ruoyi.system.domain.PocTesting;
import com.ruoyi.system.domain.ProjectManagement;
import com.ruoyi.system.domain.ProjectResearch;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Map;

/**
 * @author ZHAONZ
 * @version 1.0
 * @date 2023/6/10 10:59
 */
@Mapper
public interface MapMapper {

    MapMapper INSTANCE = Mappers.getMapper(MapMapper.class);

    @BeanMapping( ignoreByDefault = true )
    @Mapping(target = "projectId", qualifiedByName = "getLong")
    @Mapping(target = "projectNo", qualifiedByName = "getString")
    @Mapping(target = "projectBudget", qualifiedByName = "getBigDecimal")
    @Mapping(target = "projectAmount", qualifiedByName = "getBigDecimal")
    @Mapping(target = "requirementType", qualifiedByName = "getString")
    @Mapping(target = "projectResearch", qualifiedByName = "getInt")
    @Mapping(target = "pocTesting", qualifiedByName = "getInt")
    ProjectManagement toManagement(Map<String, Object> map);

    @BeanMapping( ignoreByDefault = true )
    @Mapping(target = "projectId", qualifiedByName = "getLong")
    @Mapping(target = "researchTime", source = "approvalTime", qualifiedByName = "getString", dateFormat = "yyyy-MM-dd")
    @Mapping(target = "supplier", qualifiedByName = "getString")
    @Mapping(target = "product", qualifiedByName = "getString")
    @Mapping(target = "market", qualifiedByName = "getString")
    ProjectResearch toResearch(Map<String, Object> map);

    @BeanMapping( ignoreByDefault = true )
    @Mapping(target = "projectId", qualifiedByName = "getLong")
    @Mapping(target = "researchTime", source = "approvalTime", qualifiedByName = "getString", dateFormat = "yyyy-MM-dd")
    @Mapping(target = "supplier", qualifiedByName = "getString")
    @Mapping(target = "product", qualifiedByName = "getString")
    @Mapping(target = "market", qualifiedByName = "getString")
    @Mapping(target = "testDescription", qualifiedByName = "getString")
    PocTesting toPocTesting(Map<String, Object> map);

    @BeanMapping( ignoreByDefault = true )
    @Mapping(target = "projectId", qualifiedByName = "getLong")
    @Mapping(target = "procurementMethod", qualifiedByName = "getString")
    @Mapping(target = "evaluationPrinciples", qualifiedByName = "getString")
    @Mapping(target = "bidOpeningTime", source = "approvalTime", qualifiedByName = "getString", dateFormat = "yyyy-MM-dd")
    @Mapping(target = "bidOpeningMethod", qualifiedByName = "getString")
    @Mapping(target = "placeOfBidOpening", qualifiedByName = "getString")
    @Mapping(target = "bidOpeningJudges", qualifiedByName = "getString")
    @Mapping(target = "complianceOfficer", qualifiedByName = "getString")
    @Mapping(target = "nameOfBiddingCompany1", qualifiedByName = "getString")
    @Mapping(target = "biddingCompanyBidder1", qualifiedByName = "getString")
    @Mapping(target = "biddingCompanyQuotation1", qualifiedByName = "getBigDecimal")
    @Mapping(target = "nameOfBiddingCompany2", qualifiedByName = "getString")
    @Mapping(target = "biddingCompanyBidder2", qualifiedByName = "getString")
    @Mapping(target = "biddingCompanyQuotation2", qualifiedByName = "getBigDecimal")
    @Mapping(target = "nameOfBiddingCompany3", qualifiedByName = "getString")
    @Mapping(target = "biddingCompanyBidder3", qualifiedByName = "getString")
    @Mapping(target = "biddingCompanyQuotation3", qualifiedByName = "getBigDecimal")
    InviteBids toInviteBids(Map<String, Object> map);

    default Number getNumber(final Object answer) {
        if (answer instanceof Number) {
            return (Number) answer;
        }
        if (answer instanceof String) {
            try {
                final String text = (String) answer;
                return NumberFormat.getInstance().parse(text);
            } catch (ParseException e) {
                // failure means null is returned
                return null;
            }
        }
        return null;
    }

    @Named(value = "getLong")
    default Long getLong(final Object object) {
        final Number answer = getNumber(object);
        if (answer == null) {
            return null;
        }
        if (answer instanceof Long) {
            return (Long) answer;
        }
        return Long.valueOf(answer.longValue());
    }

    @Named(value = "getString")
    default String getString(final Object object) {
        return object.toString();
    }

    default Integer getInteger(final Object object) {
        final Number answer = getNumber(object);
        if (answer == null) {
            return null;
        }
        if (answer instanceof Integer) {
            return (Integer) answer;
        }
        return Integer.valueOf(answer.intValue());
    }

    @Named(value = "getInt")
    default int getInt(Object object) {
        final Integer integerObject = getInteger(object);
        if (integerObject == null) {
            return 0;
        }
        return integerObject.intValue();
    }

    @Named(value = "getBigDecimal")
    default BigDecimal getBigDecimal(Object object) {
        String str = getString(object);
        if (StringUtils.isEmpty(str)) {
            return null;
        }
        return new BigDecimal(str);
    }
}
